/**
 * JSparrow - Une version numérique du jeu "Attention Pirates !" - Copyright (C) 2014 Black Pearl
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 */
package App.Vue;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import App.Controleur.Jeu;

/**
 * @see Source : https://gist.github.com/salamander2/4329783
 */
@SuppressWarnings("serial")
public class Panneau_Plateau extends JPanel{

	//Couleur utile au panel
	final static Color COLOURBACK =  new Color(0f,1f,0f,00);
	final static Color COLOURCELL =  new Color(0f,1f,0f,.5f); 
	final static Color COLOURGRID =  new Color(1f,0f,0f,00); 
	
	//Bordure en px de la grille
	final static int BORDERS = 0;  
	
	//Nb de case de la grille
	final static int EMPTY = 0;
	final static int XSIZE = 9; //Nb de cases horyzontales
	final static int YSIZE = 5; //Nb de cases verticales
	private int HEXSIZE;	//taille des cotés des cases in pixels
	private int SCRXSIZE; //taille verticale de la frame.
	private int SCRYSIZE; //taille horyzontale de la frame.
	
	//Cases de la grille
	int[][] board = new int[XSIZE][YSIZE];
	Vue_Case[][] caseBoard = new Vue_Case[XSIZE][YSIZE]; //Gere l'affichage bateaux
	private Image backgroundImage;
	private List<String[]> bateaux;
	
	//Controleur
	protected Jeu controleur;


	/**
	 * Créé un nouveau plateau
	 * @param bateaux Liste contenant la couleur du bateau ainsi que sa position
	 * 	tableau de String[3]{"Couleur","position X", "position Y"}
	 */
	public Panneau_Plateau(List<String[]> bateaux,Jeu controleur){

		this.controleur = controleur;
		//Règle la transparence du panel
		this.setBackground(COLOURBACK);
		this.setOpaque(false);
		
		this.bateaux = new ArrayList<String[]>();
		this.bateaux.addAll(bateaux);
		//Redimensionne le fond et la taille des hexagones pour qu'ils occupent 70% de la hauteur
		
		Rectangle screenBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
		this.HEXSIZE =(int)((screenBounds.height*0.63)/(YSIZE + 1));
		SCRXSIZE = HEXSIZE * (XSIZE-1);
		SCRYSIZE = HEXSIZE * (YSIZE+1);
		this.setPreferredSize(new Dimension(SCRXSIZE,SCRYSIZE));

		//Initialise le plateau et les bateaux
		initBoard();
		positionnementBateau(bateaux);
		Hexagone.setHeight(HEXSIZE); //Initialisation de la taille des hexagones
		Hexagone.setBorders(BORDERS);

		//Redimensionnement de l'image de fond
		try {
			BufferedImage bufferedFond = ImageIO.read(this.getClass().getClassLoader().getResourceAsStream("img/Background.jpg"));
			backgroundImage = bufferedFond.getScaledInstance(HEXSIZE * (XSIZE-1),HEXSIZE * (YSIZE)+ (int)(HEXSIZE*0.5) , 0);

		} catch (IOException e) {
			e.printStackTrace();
		}
		
		MyMouseListener ml = new MyMouseListener();            
		addMouseListener(ml);

	}

	/**
	 * Redéfinition de la méthode paintComponent. 
	 * Est appelée à chaque fois qu'il y a besoin de repeindre le panel.
	 */
	public void paintComponent(Graphics g){

		//fond de carte
		g.drawImage(backgroundImage, 0, 0, this);	

		Point pointIJ;
		//Dessine la grille en prenant en compte les cases interdites
		for (int i=0;i<XSIZE;i++) {
			for (int j=0;j<YSIZE;j++) {

				pointIJ = new Point(i,j*2 + i%2);
				if(!App.Modele.Configuration.EmplacementsInterdits.contains(pointIJ)){

					Hexagone.fillHex(i,j,board[i][j],g);
					caseBoard[i][j].drawCase(g, i, j);
				}
			}
		}

	}

	/**
	 * Initialise le plateau
	 */
	private void initBoard(){

		for (int i=0;i<XSIZE;i++) {
			for (int j=0;j<YSIZE;j++) {
				caseBoard[i][j]=new Vue_Case(HEXSIZE);
				board[i][j]=EMPTY;
			}
		}
	}

	/**
	 * Positionne les bateaux sur les cases
	 * @param bateaux Liste contenant la couleur du bateau ainsi que sa position
	 * 	tableau de String[3]{"couleur","position X", "position Y"}
	 */
	private void positionnementBateau(List<String[]> bateaux){
		int x,y;
		for (String[] boat : bateaux) {
			try{
				x=Integer.parseInt(boat[1]);
				y=Integer.parseInt(boat[2])/2;
				caseBoard[x][y].addBateau(boat[0]);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * Modifie la position des bateaux sur le plateaux
	 * @param bateaux : liste des bateaux et de leurs positions
	 */
	public void updatePlateau(List<String[]> bateaux){
		int x,y;
		//Cherche les bateaux qui ont bougés
		for (String[] boat : bateaux) {
			for (String[] boatOld : this.bateaux) {
				if((boat[0].equals(boatOld[0])) && ((!boat[1].equals(boatOld[1]))||(!boat[2].equals(boatOld[2])))){
					//Ancienne position
					x=Integer.parseInt(boatOld[1]);
					y=Integer.parseInt(boatOld[2])/2;
					caseBoard[x][y].delBateau(boat[0]);
					//Nouvelle position
					x=Integer.parseInt(boat[1]);
					y=Integer.parseInt(boat[2])/2;
					caseBoard[x][y].addBateau(boat[0]);
				}

			}
		}
		this.bateaux.clear();
		this.bateaux.addAll(bateaux);
		repaint();
	}

	/**
	 * MouseListener du plateau, pour le moment, ne sert qu'à colorer/décolorer une case
	 */
	class MyMouseListener extends MouseAdapter	{

		public void mouseClicked(MouseEvent e) { 
			Point p = new Point( Hexagone.pxtoHex(e.getX(),e.getY()) );
			if (p.x < 0 || p.y < 0 || p.x >= XSIZE || p.y >= YSIZE) return;
			Point pointIJ = new Point(p.x,p.y*2 +p.x%2);
			String element = caseBoard[p.x][p.y].haveBateau(p.x, p.y, new Point(e.getX(),e.getY()));
			//TODO : action à réaliser lors d'un clic sur un bateau
			if(!element.isEmpty()){
				controleur.infoCible(element);
				controleur.gestionEvenementVue("checkAttaquer="+element);
				controleur.gestionEvenementVue("checkDeplacer=("+pointIJ.x+";"+pointIJ.y+")");
				return;
				
			}
			//Si la case n'est pas une case interdite
			if(!App.Modele.Configuration.EmplacementsInterdits.contains(pointIJ)){
				//JOptionPane.showMessageDialog(null, pointIJ.toString());
				controleur.infoCase("(" + pointIJ.x +";" + pointIJ.y + ")");
				controleur.gestionEvenementVue("checkAttaquer=("+pointIJ.x+";"+pointIJ.y+")");
				controleur.gestionEvenementVue("checkDeplacer=("+pointIJ.x+";"+pointIJ.y+")");
			}
		}		 
	} 
}
